#ifndef FRONTEND_H_
#define FRONTEND_H_
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string>
#include <set>
#include <vector>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include "functions.h"
#include "ElectionRegistry.h"
#include "Creator.h"
#include "VotingSystems.h"

/**
 * Driver function.
 *
 * @param argc Command line argument count.
 * @param argv Command line arguments (unused).
 * @param env  Command line environmental variables (unused).
 */
int main( int argc, char** argv, char** env );

/**
 * Prints a vector of RationalVotes.
 *
 * @param votes A vector of RationalVotes
 */
void print_votes( const vector<RationalVote>& votes );

/**
 * Prints a multiset of RationalVotes.
 *
 * @param votes A multiset of RationalVotes
 */
void print_votes( const multiset<RationalVote>& votes );

/**
 * Solves the 2 manipulator problem for any scoring protocol with three scoring positions.
 *
 * @param e A positional score election
 * @param preferred The preferred candidate.
 * @param unique Boolean value determining whether or not the unique-winner problem is used. Set to true if unspecified.
 * @return Two RationalVotes if a manipulation exists, none otherwise.
 */
vector<RationalVote> two_manipulation_three_position( const PositionalScoreElection& e, const string& preferred, int unique = 1 );

/**
 * Runs the greedy algorithm on e with e's scoring protocol and the given protocols.
 *
 * @param e A Scoring Vector election.
 * @param protocols A list of scoring protocols. If not given the function generates one from e's scoring vector.
 */
pair<int,int> bound_test( const ScoringVector& e,  vector< vector<unsigned int> > protocols = vector< vector<unsigned int> >() );

/**
 * Runs the greedy algorithm on e with e's scoring protocol and the given protocols. This function generates a
 * ScoringVector election and runs the other bound_test function with it.
 *
 * @param num_votes The number of random votes to put in the election.
 * @param num_candidates The number of candidates in the election.
 * @param scoring_protocol The scoring protocol for the election.
 * @param protocols A list of scoring protocols. If not given the function generates one from scoring_protocol.
 */
pair<int,int> bound_test( const unsigned int& num_votes, const unsigned int& num_candidates, const vector<unsigned int>& scoring_protocol, const vector< vector<unsigned int> >& protocols = vector< vector<unsigned int> >() );
#endif
